package com.bjpowernode.task;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.bjpowernode.common.constant.AppConstants;
import com.bjpowernode.mvc.service.inter.IncomeRecordService;
import com.bjpowernode.mvc.service.inter.PayService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Set;


/**
 * 定时任务：生成收益计划
 */
@Slf4j
@Component
public class TimeTaskManager {

    @Resource
    private IncomeRecordService incomeRecordService;
    @Resource
    private PayService payService;

    /**
     * 定时方法
     * 1、方法是public公共的
     * 2、方法无返回值
     * 3、方法无参数
     * 4、使用@Scheduled注解  cron 从0秒开始每隔10秒执行一次
     */

    /*    @Scheduled(cron = "0/10 * * * * ?")
    public void printTimeTask() {
        System.out.println("定时任务：执行时间：" + new Date());
    }*/

    /**
     * 每天凌晨一点执行定时任务
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void generateIncomePlan() {
        incomeRecordService.generateIncomePlan();
    }

    /**
     * 每天凌晨两点生成收益返还
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void generateIncomeBack() {
        incomeRecordService.generateIncomeBack();
    }

    /**
     * 调单处理
     * 每20分钟从Redis中获取没有充值结果的订单，查询订单的支付结果
     */
    @Scheduled(cron = "0 0/20 * * * ?")
    public void taskPayQuery() {
        String json = "";
        try {
            //15分钟的毫秒值
            long minute15 = 15 * 60 * 1000;
            //从Redis中获取待查询的订单号(订单号 + 充值时间)
            Set<ZSetOperations.TypedTuple<String>> tuples = payService.getUntreatedOrderId();
            for (ZSetOperations.TypedTuple<String> tuple : tuples) {
                //1、单个订单的订单号和创建时间
                //订单号
                String orderId = tuple.getValue();
                //创建时间
                Double createTime = tuple.getScore();

                //如果执行定时任务的时间 - 创建的时间 小于 15分钟 则这个订单号不执行下面的步骤，等下次定时任务这个订单号再执行下面的步骤
                if (System.currentTimeMillis() - createTime < minute15) {
                    continue;
                }

                //2、对每个没有充值结果的订单进行订单结果的查询
                json = payService.executeQueryOrderId(orderId);
                if ("error".equals(json)) {
                    //订单查询发生异常,没有正常查询到订单的支付结果，返回失败状态为2，不删除Redis中的订单号，下次执行定时任务时继续该操作
                    log.info("调用快钱查询结构错误{}" + orderId);
                } else if (StrUtil.isNotEmpty(json)) {
                    //解析JSON
                    JSONObject jsonObject = JSONUtil.parseObj(json);
                    JSONArray orderDetail = jsonObject.getJSONArray("orderDetail");
                    //3、处理订单结果
                    if (JSONUtil.isNull(orderDetail)) {
                        //为空，没有查询到订单结果,即客户点击支付发起请求，但并没有进行支付，所以将该订单修改为失败状态2
                        payService.modifyRechargeStatus(orderId, AppConstants.STA_RECHARGE_FAIL);
                        log.info("更新订单为失败状态{}" + orderId);
                    } else {
                        //不是null，有查询结果,一个订单一个订单查询
                        JSONObject detail = (JSONObject) orderDetail.get(0);
                        //支付结果
                        String payResult = detail.getStr("payResult");
                        //实付金额
                        String payAmount = detail.getStr("payAmount");
                        //订单号
                        String PayOrderId = detail.getStr("orderId");
                        //异步通知处理
                        String notifyResult = payService.handleNotify(PayOrderId, payAmount, payResult);
                        log.info("查询订单{}-{}-{}-{}", PayOrderId, payAmount, payResult, notifyResult);
                    }

                    //2.2删除Redis中的订单号
                    payService.deleteOrderId(orderId);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
